

#ifndef _SW_TIMER_H_
#define _SW_TIMER_H_

#include "lib/type.h"

//when timer counter >= period, the counter will be reset, the timeout flag will be set;
//and the counter will keep running
//the period_timeout_callback will be called in every tick until the timeout flag was reseted by user

typedef struct{ 
 uint8_t b7	:1;
 uint8_t b6	:1;
 uint8_t b5	:1;
 uint8_t b4	:1;
 uint8_t b3	:1;
 uint8_t b2	:1;
 uint8_t timeout :1;
 uint8_t enable	:1;
}SW_TIMER_STATE_STRUCT;	

//typedef struct __SW_TIMER_STRUCT__ SW_TIMER_STRUCT;
//struct __SW_TIMER_STRUCT__{
//	uint16_t period;
//    uint16_t counter;
//    void (*period_timeout_callback)(SW_TIMER_STRUCT* sw_timer);
//    SW_TIMER_STATE_STRUCT state;
//};

struct __SW_TIMER_STRUCT__{
	uint16_t period;
    uint16_t counter;
    void (*period_timeout_callback)(struct __SW_TIMER_STRUCT__* sw_timer);
    SW_TIMER_STATE_STRUCT state;
};
typedef struct __SW_TIMER_STRUCT__ SW_TIMER_STRUCT;

void sw_timer_set_period(SW_TIMER_STRUCT* sw_timer, uint16_t period);
uint16_t sw_timer_get_period(SW_TIMER_STRUCT* sw_timer);
void sw_timer_reset_counter(SW_TIMER_STRUCT* sw_timer);
uint16_t sw_timer_get_counter(SW_TIMER_STRUCT* sw_timer);
void sw_timer_enable(SW_TIMER_STRUCT* sw_timer);
void sw_timer_disable(SW_TIMER_STRUCT* sw_timer);
uint8_t sw_timer_check_enable(SW_TIMER_STRUCT* sw_timer);
void sw_timer_reset_timeout(SW_TIMER_STRUCT* sw_timer);
uint8_t sw_timer_check_timeout(SW_TIMER_STRUCT* sw_timer);
void sw_timer_tick_handler(SW_TIMER_STRUCT* sw_timer, uint16_t ticks);
void sw_timer_init(SW_TIMER_STRUCT* sw_timer,
					uint16_t period,
					void (*period_timeout_callback_handler)(SW_TIMER_STRUCT* sw_timer));

typedef struct
{
	uint8_t sw_timer_num;
	uint8_t sw_timer_pointer;
	SW_TIMER_STRUCT* sw_timer;
} SW_TIMER_GROUP_STRUCT;

void sw_timer_group_tick_handler(SW_TIMER_GROUP_STRUCT* sw_timer_group, uint16_t ticks);
void sw_timer_group_init(SW_TIMER_GROUP_STRUCT* sw_timer_group,
                               uint8_t sw_timer_group_sw_timer_num,
                               SW_TIMER_STRUCT* sw_timer_group_space);
SW_TIMER_STRUCT* sw_timer_new(SW_TIMER_GROUP_STRUCT* sw_timer_group,
                                uint16_t period,
                                void (*period_timeout_callback_handler)(void));

#endif